<?php

namespace MathPHP\Tests\LinearAlgebra\Matrix\Numeric;

use MathPHP\LinearAlgebra\MatrixFactory;
use MathPHP\Exception;

class MatrixDeterminantTest extends \PHPUnit\Framework\TestCase
{
    use \MathPHP\Tests\LinearAlgebra\Fixture\MatrixDataProvider;

    /**
     * @test         det
     * @dataProvider dataProviderForDet
     */
    public function testDet(array $A, $expected)
    {
        // Given
        $A = MatrixFactory::create($A);

        // When
        $det = $A->det();

        // Then
        $this->assertEqualsWithDelta($expected, $det, 0.000001);
    }

    /**
     * @return array (A, det)
     */
    public function dataProviderForDet(): array
    {
        return [
            [
                [[1]], 1
            ],
            [
                [
                    [0]
                ],
                0
            ],
            [
                [
                    [1]
                ],
                1
            ],
            [
                [
                    [2]
                ],
                2
            ],
            [
                [
                    [5]
                ],
                5
            ],
            [
                [
                    [-5]
                ],
                -5
            ],
            [
                [
                    [0, 0],
                    [0, 0],
                ], 0
            ],
            [
                [
                    [0, 0],
                    [0, 1],
                ], 0
            ],
            [
                [
                    [0, 0],
                    [1, 0],
                ], 0
            ],
            [
                [
                    [0, 0],
                    [1, 1],
                ], 0
            ],
            [
                [
                    [0, 1],
                    [0, 0],
                ], 0
            ],
            [
                [
                    [0, 1],
                    [0, 1],
                ], 0
            ],
            [
                [
                    [1, 0],
                    [0, 0],
                ], 0
            ],
            [
                [
                    [1, 0],
                    [1, 0],
                ], 0
            ],
            [
                [
                    [1, 1],
                    [0, 0],
                ], 0
            ],
            [
                [
                    [1, 1],
                    [1, 1],
                ], 0
            ],
            [
                [
                    [0, 1],
                    [1, 0],
                ], -1
            ],
            [
                [
                    [0, 1],
                    [1, 1],
                ], -1
            ],
            [
                [
                    [1, 0],
                    [0, 1],
                ], 1
            ],
            [
                [
                    [1, 0],
                    [1, 1],
                ], 1
            ],
            [
                [
                    [1, 1],
                    [0, 1],
                ], 1
            ],
            [
                [
                    [1, 1],
                    [1, 0],
                ], -1
            ],
            [
                [
                    [3, 8],
                    [4, 6],
                ], -14
            ],
            [
                [
                    [4, 3],
                    [3, 2],
                ], -1
            ],
            [
                [
                    [1, 2],
                    [3, 4],
                ], -2
            ],
            [
                [
                    [1, 2],
                    [3, 4],
                ], -2
            ],
            [
                [
                    [1, 2],
                    [2, 1],
                ], -3
            ],
            [
                [
                    [1, 3],
                    [3, 1],
                ], -8
            ],
            [
                [
                    [6, 1, 1],
                    [4, -2, 5],
                    [2, 8, 7],
                ], -306
            ],
            [
                [
                    [1, 2, 0],
                    [-1, 1, 1],
                    [1, 2, 3],
                ], 9
            ],
            [
                [
                    [1, 2, 3],
                    [2, 3, 4],
                    [3, 4, 5],
                ], 0
            ],
            [
                [
                    [1, 2, 1],
                    [-2, -3, 1],
                    [3, 5, 0],
                ], 0
            ],
            [
                [
                    [1, -1, 2],
                    [2, 1, 1],
                    [1, 1, 0],
                ], 0
            ],
            [
                [
                    [1, 0, 1],
                    [0, 1, -1],
                    [0, 0, 0],
                ], 0
            ],
            [
                [
                    [1, 1, 4, 1, 2],
                    [0, 1, 2, 1, 1],
                    [0, 0, 0, 1, 2],
                    [1, -1, 0, 0, 2],
                    [2, 1, 6, 0, 1],
                ], 0
            ],
            [
                [
                    [4, 6, 3, 2],
                    [3, 6, 5, 3],
                    [5, 7, 8, 6],
                    [5, 4, 3, 2],
                ], -43
            ],
            [
                [
                    [3, 2, 0, 1],
                    [4, 0, 1, 2],
                    [3, 0, 2, 1],
                    [9, 2, 3, 1],
                ], 24
            ],
            [
                [
                    [1, 2, 3, 4],
                    [5, 6, 7, 8],
                    [2, 6, 4, 8],
                    [3, 1, 1, 2],
                ], 72
            ],
            [
                [
                    [7, 4, 2, 0],
                    [6, 3, -1, 2],
                    [4, 6, 2, 5],
                    [8, 2, -7, 1],
                ], -279
            ],
            [
                [
                    [-4, 3, 1, 5, -8],
                    [6, 0, 9, 2, 6],
                    [-1, 4, 4, 0, 2],
                    [8, -1, 3, 4, 0],
                    [5, 9, -7, -7, 1]
                ],
                -5763
            ],
            [
                [
                    [4, 3, 1, 5, -8],
                    [6, 0, 9, 2, 6],
                    [-1, 4, 4, 0, 2],
                    [8, -1, 3, 4, 0],
                    [5, 9, -7, -7, 1]
                ],
                -10035
            ],
            [
                [
                    [4, 3, 1, 5, 8],
                    [6, 0, 9, 2, 6],
                    [-1, 4, 4, 0, 2],
                    [8, -1, 3, 4, 0],
                    [5, 9, -7, -7, 1]
                ],
                32157
            ],
            [
                [
                    [4, 3, 1, 5, 8],
                    [6, 0, 9, 2, 6],
                    [1, 4, 4, 0, 2],
                    [8, -1, 3, 4, 0],
                    [5, 9, -7, -7, 1]
                ],
                28287
            ],
            [
                [
                    [4, 3, 1, 5, 8],
                    [6, 0, 9, 2, 6],
                    [1, 4, 4, 0, 2],
                    [8, 1, 3, 4, 0],
                    [5, 9, -7, -7, 1]
                ],
                30357
            ],
            [
                [
                    [4, 3, 1, 5, 8],
                    [6, 0, 9, 2, 6],
                    [1, 4, 4, 0, 2],
                    [8, 1, 3, 4, 0],
                    [5, 9, 7, -7, 1]
                ],
                17953
            ],
            [
                [
                    [4, 3, 1, 5, 8],
                    [6, 0, 9, 2, 6],
                    [1, 4, 4, 0, 2],
                    [8, 1, 3, 4, 0],
                    [5, 9, 7, 7, 1]
                ],
                -11615
            ],
            [
                [
                    [5, 2, 0, 0, -2],
                    [0, 1, 4, 3, 2],
                    [0, 0, 2, 6, 3],
                    [0, 0, 3, 4, 1],
                    [0, 0, 0, 0, 2],
                ],
                -100
            ],
            [
                [
                    [5, 2, 0, 0, 2],
                    [0, 1, 4, 3, 2],
                    [0, 0, 2, 6, 3],
                    [0, 0, 3, 4, 1],
                    [0, 0, 0, 0, 2],
                ],
                -100
            ],
            [
                [
                    [5, 2, 0, 0, -2],
                    [0, -1, 4, 3, 2],
                    [0, 0, 2, 6, 3],
                    [0, 0, 3, 4, 1],
                    [0, 0, 0, 0, 2],
                ],
                100
            ],
            [
                [
                    [2, -9, 1, 8, 4],
                    [-10, -1, 2, 7, 0],
                    [0, 4, -6, 1, -8],
                    [6, -14, 11, 0, 3],
                    [5, 1, -3, 2, -1],
                ],
                30143
            ],
            [
                [
                    [2, 9, 1, 8, 4],
                    [-10, -1, 2, 7, 0],
                    [0, 4, -6, 1, -8],
                    [6, -14, 11, 0, 3],
                    [5, 1, -3, 2, -1],
                ],
                -55105
            ],
            [
                [
                    [2, 9, 1, 8, 4],
                    [10, -1, 2, 7, 0],
                    [0, 4, -6, 1, -8],
                    [6, -14, 11, 0, 3],
                    [5, 1, -3, 2, -1],
                ],
                -5
            ],
            [
                [
                    [2, 9, 1, 8, 4],
                    [10, 1, 2, 7, 0],
                    [0, 4, -6, 1, -8],
                    [6, -14, 11, 0, 3],
                    [5, 1, -3, 2, -1],
                ],
                6929
            ],
            [
                [
                    [276,1,179,23, 9387],
                    [0, 0, 78, 0, 0],
                    [0, 0, -1, 0, 1],
                    [0, 0, 1994, -1, 1089],
                    [1, 0, 212, 726, -378],
                ],
                78
            ],
            [
                [
                    [276,1,179,23, 9387],
                    [0, 0, 78, 0, 0],
                    [0, 0, 1, 0, 1],
                    [0, 0, 1994, -1, 1089],
                    [1, 0, 212, 726, -378],
                ],
                78
            ],
            [
                [
                    [276,1,179,23, 9387],
                    [0, 0, 78, 0, 0],
                    [0, 0, 1, 0, 1],
                    [0, 0, 1994, 1, 1089],
                    [1, 0, 212, 726, -378],
                ],
                -78
            ],
            [
                [
                    [276,1,179,23, 9387],
                    [0, 0, 78, 0, 0],
                    [0, 0, 1, 0, 1],
                    [0, 0, 1994, 1, 1089],
                    [1, 0, 212, 726, 378],
                ],
                -78
            ],
            [
                [
                    [276,1,179,23, -9387],
                    [0, 0, 78, 0, 0],
                    [0, 0, 1, 0, 1],
                    [0, 0, 1994, 1, 1089],
                    [1, 0, 212, 726, 378],
                ],
                -78
            ],
            [
                [
                    [1, 2, 3, 4, 5],
                    [2, 3, 4, 5, 6],
                    [5, 4, 3, 2, 1],
                    [4, 3, 2, 1, 0],
                    [1, 3, 5, 7, 9],
                ],
                0
            ],
            [
                [
                    [1, 0, 3, 5, 1],
                    [0, 1, 5, 1, 0],
                    [0, 4, 0, 0, 2],
                    [2, 3, 1, 2, 0],
                    [1, 0, 0, 1, 1],
                ],
                230
            ],
            [
                [
                    [2, 3, 4, 1, 3],
                    [6, 1, 3, 1, 2],
                    [6, 3, 1, 2, 5],
                    [4, 2, 4, 7, 8],
                    [2, 1, 2, 4, 2],
                ],
                -1016
            ],
            [
                [
                    [2, 3, -4, 1, 3],
                    [6, 1, 3, 1, 2],
                    [6, 3, 1, 2, 5],
                    [4, 2, 4, 7, 8],
                    [2, 1, 2, 4, 2],
                ],
                296
            ],
            [
                [
                    [2, 3, -4, 1, 3],
                    [6, 1, -3, 1, 2],
                    [6, 3, 1, 2, 5],
                    [4, 2, 4, 7, 8],
                    [2, 1, 2, 4, 2],
                ],
                1280
            ],
            [
                [
                    [2, 3, -4, 1, 3],
                    [6, 1, -3, 1, 2],
                    [6, 3, -1, 2, 5],
                    [4, 2, 4, 7, 8],
                    [2, 1, 2, 4, 2],
                ],
                808
            ],
            [
                [
                    [2, 3, -4, 1, 3],
                    [6, 1, -3, 1, 2],
                    [6, 3, -1, 2, 5],
                    [4, 2, -4, 7, 8],
                    [2, 1, 2, 4, 2],
                ],
                1320
            ],
            [
                [
                    [2, 3, -4, 1, 3],
                    [6, 1, -3, 1, 2],
                    [6, 3, -1, 2, 5],
                    [4, 2, -4, 7, 8],
                    [2, 1, -2, 4, 2],
                ],
                1016
            ],
            [
                [
                    [2, 3, -4, -1, 3],
                    [6, 1, -3, 1, 2],
                    [6, 3, -1, 2, 5],
                    [4, 2, -4, 7, 8],
                    [2, 1, -2, 4, 2],
                ],
                1176
            ],
            [
                [
                    [2, 3, -4, -1, -3],
                    [6, 1, -3, -1, 2],
                    [6, 3, -1, 2, 5],
                    [4, 2, -4, 7, -8],
                    [2, 1, -2, 4, 2],
                ],
                -3664
            ],
            [
                [
                    [2, 1, 2],
                    [1, 1, 1],
                    [2, 2, 5],
                ],
                3
            ],
            [
                [
                    [1, 0, 2, -1],
                    [3, 0, 0, 5],
                    [2, 1, 4, -3],
                    [1, 0, 5, 0],
                ],
                30
            ],
            [
                [
                    [1, 0, 2, 0, 0, 4],
                    [18, 1, 5, 0, 0, 9],
                    [3, 5, 3, 6, 0, 4],
                    [2, 0, 8, 0, 0, 7],
                    [7, 0, 4, 0, 6, 0],
                    [0, 0, 1, 0, 0, 0]
                ],
                -36
            ],
            [
                [
                    [-1, 0, 2, 0, 0, 4],
                    [18, 1, 5, 0, 0, 9],
                    [3, 5, 3, 6, 0, 4],
                    [2, 0, 8, 0, 0, 7],
                    [7, 0, 4, 0, 6, 0],
                    [0, 0, 1, 0, 0, 0]
                ],
                -540
            ],
            [
                [
                    [-1, 0, -2, 0, 0, 4],
                    [18, 1, 5, 0, 0, 9],
                    [3, 5, 3, 6, 0, 4],
                    [2, 0, 8, 0, 0, 7],
                    [7, 0, 4, 0, 6, 0],
                    [0, 0, 1, 0, 0, 0]
                ],
                -540
            ],
            [
                [
                    [-1, 0, -2, 0, 0, -4],
                    [18, 1, 5, 0, 0, 9],
                    [3, 5, 3, 6, 0, 4],
                    [2, 0, 8, 0, 0, 7],
                    [7, 0, 4, 0, 6, 0],
                    [0, 0, 1, 0, 0, 0]
                ],
                36
            ],
            [
                [
                    [1, 1, 1, 1, 1,  1],
                    [1, 3, 1, 3, 1,  3],
                    [1, 1, 4, 1, 1,  4],
                    [1, 3, 1, 7, 1,  3],
                    [1, 1, 1, 1, 6,  1],
                    [1, 3, 4, 3, 1, 12]
                ],
                720
            ],
            [
                [
                    [-1, 1, 1, 1, 1, 1],
                    [1, 3, 1, 3, 1,  3],
                    [1, 1, 4, 1, 1,  4],
                    [1, 3, 1, 7, 1,  3],
                    [1, 1, 1, 1, 6,  1],
                    [1, 3, 4, 3, 1, 12]
                ],
                -2448
            ],
            [
                [
                    [-1, 1, 1, 1, 1, 1],
                    [1, 3, 1, 3, 1,  3],
                    [1, 1, 4, 1, 1,  4],
                    [1, -3, 1, 7, 1, 3],
                    [1, 1, 1, 1, 6,  1],
                    [1, 3, 4, 3, 1, 12]
                ],
                -6120
            ],
            [
                [
                    [1, 0, 0, 0, 0, 0],
                    [0, 2, 0, 0, 0, 0],
                    [0, 0, 3, 0, 0, 0],
                    [0, 0, 0, 4, 0, 0],
                    [0, 0, 0, 0, 5, 0],
                    [0, 0, 0, 0, 0, 6]
                ],
                720
            ],
            [
                [
                    [-1, 0, 0, 0, 0, 0],
                    [0, 2, 0, 0, 0, 0],
                    [0, 0, 3, 0, 0, 0],
                    [0, 0, 0, 4, 0, 0],
                    [0, 0, 0, 0, 5, 0],
                    [0, 0, 0, 0, 0, 6]
                ],
                -720
            ],
            [
                [
                    [-1, 0, 0, 0, 0, 0],
                    [0, 2, 0, 0, 0, 0],
                    [0, 0, 0, 4, 0, 0],
                    [0, 0, 3, 0, 0, 0],
                    [0, 0, 0, 0, 5, 0],
                    [0, 0, 0, 0, 0, 6]
                ],
                720
            ],
            [
                [
                    [1, 0, 0, 0, 0, 0],
                    [1, 2, 0, 0, 0, 0],
                    [1, 0, 3, 0, 0, 0],
                    [1, 2, 0, 4, 0, 0],
                    [1, 0, 0, 0, 5, 0],
                    [1, 2, 3, 0, 0, 6],
                ],
                720
            ],
            [
                [
                    [0, 1, 4, 3, 2, 3, 3, 4, 4],
                    [1, 0, 3, 2, 1, 2, 2, 3, 3],
                    [4, 3, 0, 1, 2, 3, 3, 4, 4],
                    [3, 2, 1, 0, 1, 2, 2, 3, 3],
                    [2, 1, 2, 1, 0, 1, 1, 2, 2],
                    [3, 2, 3, 2, 1, 0, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 0, 1, 2],
                    [4, 3, 4, 3, 2, 3, 1, 0, 2],
                    [4, 3, 4, 3, 2, 3, 2, 2, 0],
                ],
                1472
            ],
            [
                [
                    [0, 1, 4, 3, 2, 3, 3, 4, 4],
                    [-1, 0, 3, 2, 1, 2, 2, 3, 3],
                    [4, 3, 0, 1, 2, 3, 3, 4, 4],
                    [3, 2, 1, 0, 1, 2, 2, 3, 3],
                    [2, 1, 2, 1, 0, 1, 1, 2, 2],
                    [3, 2, 3, 2, 1, 0, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 0, 1, 2],
                    [4, 3, 4, 3, 2, 3, 1, 0, 2],
                    [4, 3, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [2, 1, 4, 3, 2, 3, 3, 4, 4],
                    [1, 2, 3, 2, 1, 2, 2, 3, 3],
                    [4, 3, 2, 1, 2, 3, 3, 4, 4],
                    [3, 2, 1, 2, 1, 2, 2, 3, 3],
                    [2, 1, 2, 1, 2, 1, 1, 2, 2],
                    [3, 2, 3, 2, 1, 2, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 2, 1, 2],
                    [4, 3, 4, 3, 2, 3, 1, 2, 2],
                    [4, 3, 4, 3, 2, 3, 2, 2, 2],
                ],
                128
            ],
            [
                [
                    [2, -1, 4, 3, 2, 3, 3, 4, 4],
                    [1, 2, 3, 2, 1, 2, 2, 3, 3],
                    [4, 3, 2, 1, 2, 3, 3, 4, 4],
                    [3, 2, 1, 2, 1, 2, 2, 3, 3],
                    [2, 1, 2, 1, 2, 1, 1, 2, 2],
                    [3, 2, 3, 2, 1, 2, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 2, 1, 2],
                    [4, 3, 4, 3, 2, 3, 1, 2, 2],
                    [4, 3, 4, 3, 2, 3, 2, 2, 2],
                ],
                256
            ],
            [
                [
                    [2, 1, 4, 3, 2, 3, 3, 4, 4],
                    [-1, 2, 3, 2, 1, 2, 2, 3, 3],
                    [4, 3, 2, 1, 2, 3, 3, 4, 4],
                    [3, 2, 1, 2, 1, 2, 2, 3, 3],
                    [2, 1, 2, 1, 2, 1, 1, 2, 2],
                    [3, 2, 3, 2, 1, 2, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 2, 1, 2],
                    [4, 3, 4, 3, 2, 3, 1, 2, 2],
                    [4, 3, 4, 3, 2, 3, 2, 2, 2],
                ],
                256
            ],
            [
                [
                    [2, -1, 4, 3, 2, 3, 3, 4, 4],
                    [-1, 2, 3, 2, 1, 2, 2, 3, 3],
                    [4, 3, 2, 1, 2, 3, 3, 4, 4],
                    [3, 2, 1, 2, 1, 2, 2, 3, 3],
                    [2, 1, 2, 1, 2, 1, 1, 2, 2],
                    [3, 2, 3, 2, 1, 2, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 2, 1, 2],
                    [4, 3, 4, 3, 2, 3, 1, 2, 2],
                    [4, 3, 4, 3, 2, 3, 2, 2, 2],
                ],
                512
            ],
            [
                [
                    [2, -1, 4, 3, 2, 3, 3, 4, 4],
                    [-1, 2, 3, 2, 1, 2, 2, 3, 3],
                    [4, 3, 2, 1, 2, 3, 3, 4, 4],
                    [2, 1, 2, 1, 2, 1, 1, 2, 2],
                    [3, 2, 1, 2, 1, 2, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 2, 1, 2],
                    [4, 3, 4, 3, 2, 3, 1, 2, 2],
                    [4, 3, 4, 3, 2, 3, 2, 2, 2],
                ],
                -512
            ],
            [
                [
                    [2, -1, 4, 3, 2, 3, 4, 4],
                    [-1, 2, 3, 2, 1, 2, 3, 3],
                    [4, 3, 2, 1, 2, 3, 4, 4],
                    [2, 1, 2, 1, 2, 1, 2, 2],
                    [3, 2, 3, 2, 1, 2, 3, 3],
                    [3, 2, 3, 2, 1, 2, 1, 2],
                    [4, 3, 4, 3, 2, 1, 2, 2],
                    [4, 3, 4, 3, 2, 2, 2, 2],
                ],
                -96,
            ],
            [
                [
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [3, 0, 1, 2, 3, 3, 4, 4],
                    [2, 1, 0, 1, 2, 2, 3, 3],
                    [1, 2, 1, 0, 1, 1, 2, 2],
                    [2, 3, 2, 1, 0, 2, 3, 3],
                    [2, 3, 2, 1, 2, 0, 1, 2],
                    [3, 4, 3, 2, 3, 1, 0, 2],
                    [3, 4, 3, 2, 3, 2, 2, 0],
                ],
                -640
            ],
            [
                [
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                -736
            ],
            [
                [
                    [1, 4, 3, 2, 3, 3, 4, 4],
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [2, 1, 0, 1, 2, 2, 3, 3],
                    [1, 2, 1, 0, 1, 1, 2, 2],
                    [2, 3, 2, 1, 0, 2, 3, 3],
                    [2, 3, 2, 1, 2, 0, 1, 2],
                    [3, 4, 3, 2, 3, 1, 0, 2],
                    [3, 4, 3, 2, 3, 2, 2, 0],
                ],
                96
            ],
            [
                [
                    [1, 4, 3, 2, 3, 3, 4, 4],
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [3, 0, 1, 2, 3, 3, 4, 4],
                    [1, 2, 1, 0, 1, 1, 2, 2],
                    [2, 3, 2, 1, 0, 2, 3, 3],
                    [2, 3, 2, 1, 2, 0, 1, 2],
                    [3, 4, 3, 2, 3, 1, 0, 2],
                    [3, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [1, 4, 3, 2, 3, 3, 4, 4],
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [3, 0, 1, 2, 3, 3, 4, 4],
                    [2, 1, 0, 1, 2, 2, 3, 3],
                    [2, 3, 2, 1, 0, 2, 3, 3],
                    [2, 3, 2, 1, 2, 0, 1, 2],
                    [3, 4, 3, 2, 3, 1, 0, 2],
                    [3, 4, 3, 2, 3, 2, 2, 0],
                ],
                -224
            ],
            [
                [
                    [1, 4, 3, 2, 3, 3, 4, 4],
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [3, 0, 1, 2, 3, 3, 4, 4],
                    [2, 1, 0, 1, 2, 2, 3, 3],
                    [1, 2, 1, 0, 1, 1, 2, 2],
                    [2, 3, 2, 1, 2, 0, 1, 2],
                    [3, 4, 3, 2, 3, 1, 0, 2],
                    [3, 4, 3, 2, 3, 2, 2, 0],
                ],
                -96
            ],
            [
                [
                    [1, 4, 3, 2, 3, 3, 4, 4],
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [3, 0, 1, 2, 3, 3, 4, 4],
                    [2, 1, 0, 1, 2, 2, 3, 3],
                    [1, 2, 1, 0, 1, 1, 2, 2],
                    [2, 3, 2, 1, 0, 2, 3, 3],
                    [3, 4, 3, 2, 3, 1, 0, 2],
                    [3, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [1, 4, 3, 2, 3, 3, 4, 4],
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [3, 0, 1, 2, 3, 3, 4, 4],
                    [2, 1, 0, 1, 2, 2, 3, 3],
                    [1, 2, 1, 0, 1, 1, 2, 2],
                    [2, 3, 2, 1, 0, 2, 3, 3],
                    [2, 3, 2, 1, 2, 0, 1, 2],
                    [3, 4, 3, 2, 3, 2, 2, 0],
                ],
                -64
            ],
            [
                [
                    [1, 4, 3, 2, 3, 3, 4, 4],
                    [0, 3, 2, 1, 2, 2, 3, 3],
                    [3, 0, 1, 2, 3, 3, 4, 4],
                    [2, 1, 0, 1, 2, 2, 3, 3],
                    [1, 2, 1, 0, 1, 1, 2, 2],
                    [2, 3, 2, 1, 0, 2, 3, 3],
                    [2, 3, 2, 1, 2, 0, 1, 2],
                    [3, 4, 3, 2, 3, 1, 0, 2],
                ],
                64
            ],
            [
                [
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                -736
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                -1472
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                -736
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 4, 3, 2, 3, 3, 4, 4],
                    [1, 3, 2, 1, 2, 2, 3, 3],
                    [4, 0, 1, 2, 3, 3, 4, 4],
                    [3, 1, 0, 1, 2, 2, 3, 3],
                    [2, 2, 1, 0, 1, 1, 2, 2],
                    [3, 3, 2, 1, 0, 2, 3, 3],
                    [3, 3, 2, 1, 2, 0, 1, 2],
                    [4, 4, 3, 2, 3, 1, 0, 2],
                ],
                0
            ],
            [
                [
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                96
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                -640
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                -736
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                -224
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                -96
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 2, 2, 0],
                ],
                -64
            ],
            [
                [
                    [0, 1, 3, 2, 3, 3, 4, 4],
                    [1, 0, 2, 1, 2, 2, 3, 3],
                    [4, 3, 1, 2, 3, 3, 4, 4],
                    [3, 2, 0, 1, 2, 2, 3, 3],
                    [2, 1, 1, 0, 1, 1, 2, 2],
                    [3, 2, 2, 1, 0, 2, 3, 3],
                    [3, 2, 2, 1, 2, 0, 1, 2],
                    [4, 3, 3, 2, 3, 1, 0, 2],
                ],
                64
            ],
            [
                [
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                -736
            ],
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                -1472
            ],
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                -736
            ],
            // If zero-values are not handled properly the pivots will be incorrect in this example
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 2, 2, 0],
                ],
                0
            ],
            [
                [
                    [0, 1, 4, 2, 3, 3, 4, 4],
                    [1, 0, 3, 1, 2, 2, 3, 3],
                    [4, 3, 0, 2, 3, 3, 4, 4],
                    [3, 2, 1, 1, 2, 2, 3, 3],
                    [2, 1, 2, 0, 1, 1, 2, 2],
                    [3, 2, 3, 1, 0, 2, 3, 3],
                    [3, 2, 3, 1, 2, 0, 1, 2],
                    [4, 3, 4, 2, 3, 1, 0, 2],
                ],
                0
            ],
            [
                [
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                -224
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                -736
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                -224
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                -736
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                -2544
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                -512
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                736
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 2, 2, 0],
                ],
                272
            ],
            [
                [
                    [0, 1, 4, 3, 3, 3, 4, 4],
                    [1, 0, 3, 2, 2, 2, 3, 3],
                    [4, 3, 0, 1, 3, 3, 4, 4],
                    [3, 2, 1, 0, 2, 2, 3, 3],
                    [2, 1, 2, 1, 1, 1, 2, 2],
                    [3, 2, 3, 2, 0, 2, 3, 3],
                    [3, 2, 3, 2, 2, 0, 1, 2],
                    [4, 3, 4, 3, 3, 1, 0, 2],
                ],
                96
            ],
        ];
    }

    /**
     * @test det exception - not square
     */
    public function testDetExceptionNotSquareMatrix()
    {
        // Given
        $A = MatrixFactory::create([[1, 2, 3]]);

        // Then
        $this->expectException(Exception\MatrixException::class);

        // When
        $A->det();
    }

    /**
     * @test         det
     * @dataProvider dataProviderForSingularMatrix
     * @param        array $A
     */
    public function testDetOfSingularMatrixIsZero(array $A)
    {
        // Given
        $A = MatrixFactory::create($A);

        // When
        $det = $A->det();

        // Then
        $this->assertEqualsWithDelta(0, $det, 0.000001);
    }

    /**
     * @test         det
     * @dataProvider dataProviderForNonSingularMatrix
     * @param        array $A
     */
    public function testDetOfNonSingularMatrixIsNonZero(array $A)
    {
        // Given
        $A = MatrixFactory::create($A);

        // When
        $det = $A->det();

        // Then
        $this->assertNotEqualsWithDelta(0, $det, 0.000001, '');
    }
}
